import os
import time
import random
import pandas as pd
import matplotlib

matplotlib.use('Agg')  # ✅ 关键：使用非 GUI 后端
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from flask import Flask, request, jsonify
import config  # ✅ 导入 config.py 以获取输出目录

app = Flask(__name__)

# ✅ 判断系统环境
if os.name == "nt":  # Windows
    print("正在使用 Windows 环境...")
    plt.rcParams["font.family"] = "SimHei"  # Windows 默认使用黑体
elif os.name == "posix":  # Linux
    print("正在使用 Linux 环境...")
    font_path = "/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc"

    if os.path.exists(font_path):
        my_font = fm.FontProperties(fname=font_path)
        plt.rcParams["font.family"] = my_font.get_name()
        print(f"✅ 成功加载 Linux 字体: {my_font.get_name()}")
    else:
        print("⚠️ [警告] 未找到 wqy-zenhei，使用 DejaVu Sans 作为备用字体！")
        plt.rcParams["font.family"] = "DejaVu Sans"

# ✅ 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False

# ✅ 强制删除 Matplotlib 缓存（防止字体问题）
matplotlib_cache = os.path.expanduser("~/.cache/matplotlib")
if os.path.exists(matplotlib_cache):
    import shutil

    shutil.rmtree(matplotlib_cache)
    print("✅ Matplotlib 字体缓存已清除，确保字体设置生效。")


def outlier_detection(xlsx_file, feature1, feature2, select_feature):
    """
    异常点检测函数，返回异常数据行号
    """
    # ✅ 生成唯一文件名
    timestamp = int(time.time() * 1000)
    random_number = random.randint(1000, 9999)
    output_filename = f"{timestamp}_{random_number}.png"

    # ✅ 确保输出文件夹存在
    output_dir = config.OUTPUT_FOLDER_ONE
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    output_file = os.path.join(output_dir, output_filename)

    # ✅ 读取 Excel 数据
    df = pd.read_excel(xlsx_file, engine='openpyxl')

    X = df[select_feature]

    # ✅ 数据标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # ✅ 训练孤立森林模型
    clf = IsolationForest(contamination=0.1, random_state=42)
    clf.fit(X_scaled)

    # ✅ 预测异常点
    df['anomaly'] = clf.predict(X_scaled)

    # ✅ 获取异常点行号 (排除表头行，即 index 0)
    anomaly_rows = df[df['anomaly'] == -1].index.tolist()

    # 删除索引为 0 的行（即表头行）
    if 0 in anomaly_rows:
        anomaly_rows.remove(0)

    # ✅ 计算异常点 & 正常点数量
    num_anomalies = len(anomaly_rows)
    num_normals = len(df) - num_anomalies

    # ✅ 绘制异常点可视化
    plt.figure(figsize=(10, 6))
    plt.scatter(df[feature1][df['anomaly'] == 1], df[feature2][df['anomaly'] == 1],
                label="正常点", alpha=0.6)
    plt.scatter(df[feature1][df['anomaly'] == -1], df[feature2][df['anomaly'] == -1],
                label="异常点", color="red", alpha=0.8)

    plt.xlabel(feature1)
    plt.ylabel(feature2)
    plt.title("异常点检测可视化")
    plt.legend()

    # ✅ 保存图像
    plt.savefig(output_file)
    plt.close()

    print(f"✅ 异常点检测完成，散点图已保存为: {output_file}")

    return anomaly_rows, num_anomalies, num_normals, output_file
